/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import {
  defaultIfEmpty,
  every,
  take,
  map,
  combineAll,
  concatAll,
  delay,
  mergeAll,
  pairwise,
  mapTo,
  startWith,
  withLatestFrom,
  concat,
  merge,
  bufferCount,
  bufferTime,
  bufferToggle,
  bufferWhen,
  concatMap,
  mergeMap,
  concatMapTo,
  exhaustMap,
  expand,
  groupBy,
  pluck,
  reduce,
  scan,
  switchMap,
  window,
  windowCount,
  tap,
  windowTime,
  windowToggle,
  windowWhen,
  throwError,
  debounce,
  debounceTime,
  distinctUntilChanged,
  filter,
  takeWhile,
  throttle,
  first,
  ignoreElements,
  last,
  sample,
  single,
  skip,
  skipUntil,
  skipWhile,
  takeUntil,
  retry,
  retryWhen,
  interval,
  timer,
  combineLatest,
  of,
  forkJoin,
  race,
  zip,
  from,
  partition,
  Observable,
  empty,
  range,
  Subject,
  share,
  shareReplay,
  publish,
  multicast,
  asyncScheduler,
  asapScheduler,
  queueScheduler,
  observeOn,
  Notification,
  delayWhen,
  dematerialize,
  catchError,
  timeout
} from './rxjs.js';
import Log from "./log.js"
//create
function create_Test() {
  let observable;
  let startTime = Date.now();
  for (let i = 0; i < 100000; i++) { 
    observable = Observable.create((observer) => {
      observer.next('Hello');
      observer.next('World');
      observer.complete();
    });
  }
  let endTime = Date.now();
  print(`rxjs_test_create: ${endTime - startTime} ms`);
  const observer = {
    next: (x) => {
      // print('create--' + x)
    },
    error: (err) => {
      // print('create--Observer got an error: ' + err)
    },
    complete: () => {
      // print('create--complete')
    },
  };
  observable.subscribe(observer);
}

//range(1, 10)
function range_Test() {
  let source;
  let startTime = Date.now();
  for (let i = 0; i < 100000; i++) { 
    source = range(1, 10);
  }
  let endTime = Date.now();
  print(`rxjs_test_range: ${endTime - startTime} ms`);
  source.subscribe((val) => {
    // print('rang--' + val)
  });
  
}

//distinctUntilChanged
function distinctUntilChanged_Test() {
  const myArrayWithDuplicatesInARow = from([1, 1, 2, 2, 3, 1, 2, 3]);
  let distinctUntilChanged1;
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) { 
    distinctUntilChanged1 = distinctUntilChanged()
  }
  let endTime = Date.now();
  myArrayWithDuplicatesInARow
  .pipe(distinctUntilChanged1)
  .subscribe(val => {
    // print('distinctUntilChanged--' + val)
  });
  print(`rxjs_test_distinctUntilChanged: ${endTime - startTime} ms`);
}

//multicast:subject
function multicast_Test() {
  const source = from([1, 2, 3]);
  const subject = new Subject();
  let multicast1;
  let startTime = Date.now();
  for (let i = 0; i < 100000; i++) { 
    multicast1 = multicast(subject)
  }
  let endTime = Date.now();
  let multicasted = source.pipe(multicast1);
  print(`rxjs_test_multicast: ${endTime - startTime} ms`);
  multicasted.subscribe({
    // next: (v) => print(`multicast--A:${v}`)
  })
  multicasted.subscribe({
    // next: (v) => print(`multicast--B:${v}`)
  })
  multicasted.subscribe({
    // next: (v) => print(`multicast--C:${v}`)
  })
  multicasted.connect();
}

//concat(sourceOne, sourceTwo)
function concat_Test() {
  const sourceOne = of(1, 2, 3);
  const sourceTwo = of(4, 5, 6);
  let example;
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) { 
    example = concat(sourceOne, sourceTwo);
  }
  let endTime = Date.now();
  print(`rxjs_test_concat: ${endTime - startTime} ms`);
  example.subscribe((val) => {
    // print('concat--' + val);
  });
}

//throwError: string
function throwError_Test() {
  let source;
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) { 
    source = throwError('This is an error!');
  }
  let endTime = Date.now();
  const example = source.pipe(catchError((val) => of(`I caught: ${val}`)));
  example.subscribe((val) => {
    // print('catchError--' + val);
  });
  print(`rxjs_test_throwError: ${endTime - startTime} ms`);
  
}


//defaultIfEmpty
function defaultIfEmpty_Test() {
  let exampleOne;
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) { 
    exampleOne = of().pipe(defaultIfEmpty('Observable.of() Empty!'));
  }
  let endTime = Date.now();
  exampleOne.subscribe((val) => {
    // print('defaultIfEmpty--' + val);
  });
  print(`rxjs_test_defaultIfEmpty: ${endTime - startTime} ms`);
}


//dematerialize
function dematerialize_Test() {
  let source;
  let startTime = Date.now();
  let dematerialize1;
  for (let i = 0; i < 100000; i++) { 
    dematerialize1 = dematerialize();
  }
  let endTime = Date.now();
  source = from([
    Notification.createNext('SUCCESS!'),
    Notification.createError('ERROR!')
  ]).pipe(
    dematerialize1
  )
  source.subscribe({
    // next: (val) => print(`dematerialize--NEXT VALUE: ${val}`),
    // error: (val) => print(`dematerialize--ERROR VALUE: ${val}`)
  });
  print(`rxjs_test_dematerialize: ${endTime - startTime} ms`);
 
}

//observeOn: asyncScheduler
function observeOn_Test() {
  let observeOn1;
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) { 
    observeOn1 = observeOn(asyncScheduler);
  }
  let endTime = Date.now();
  let observable = new Observable((proxyObserver) => {
    proxyObserver.next(1);
    proxyObserver.next(2);
    proxyObserver.next(3);
    proxyObserver.complete();
  }).pipe(
    observeOn1
  );
  let finalObserver = {
    next(x) {
      // print('async--got value ' + x)
    },
    error(err) {
      // print('async--something wrong occurred: ' + err);
    },
    complete() {
      // print('async--done');
    }
  };
  observable.subscribe(finalObserver);
  
  print(`rxjs_test_observeOn: ${endTime - startTime} ms`);
  
}


function taps() {
  const source = of(1, 2, 3, 4, 5);
  const example = source.pipe(
    tap(val => Log.showLog(`tap--BEFORE MAP: ${val}`)),
    map(val => val + 10),
    tap(val => Log.showLog(`tap--AFTER MAP: ${val}`))
  );

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      tap(val => Log.showLog(`tap--BEFORE MAP: ${val}`)),
      map(val => val + 10),
      tap(val => Log.showLog(`tap--AFTER MAP: ${val}`))
    );
  }
  let end = Date.now()
  print("rxjs_test_tap: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function delays() {
  const example = of(null);
  const message = merge(
    example.pipe(mapTo('Hello')),
    example.pipe(
      mapTo('World!'),
      delay(2000)
    ),
    example.pipe(
      mapTo('Goodbye'),
      delay(2000)
    ),
    example.pipe(
      mapTo('World!'),
      delay(3000)
    )
  );
  const subscribe = message.subscribe(val => Log.showLog('delay--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = merge(
      example.pipe(mapTo('Hello')),
      example.pipe(
        mapTo('World!'),
        delay(2000)
      ),
      example.pipe(
        mapTo('Goodbye'),
        delay(2000)
      ),
      example.pipe(
        mapTo('World!'),
        delay(3000)
      )
    );
  }
  let end = Date.now()
  print("rxjs_test_delay: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function delayWhens() {
  const message = interval(2000);
  const delayForFiveSeconds = () => timer(5000);
  const delayWhenExample = message.pipe(delayWhen(delayForFiveSeconds), take(5));
  const subscribe = delayWhenExample.subscribe(val => Log.showLog('delayWhen--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = message.pipe(delayWhen(delayForFiveSeconds), take(5));
  }
  let end = Date.now()
  print("rxjs_test_delayWhen: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function dematerializes() {
  const source = from([
    Notification.createNext('SUCCESS!'),
    Notification.createError('ERROR!')
  ]).pipe(
    dematerialize()
  )
  const subscription = source.subscribe({
    next: val => Log.showLog(`dematerialize--NEXT VALUE: ${val}`),
    error: val => Log.showLog(`dematerialize--ERROR VALUE: ${val}`)
  });

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = from([
      Notification.createNext('SUCCESS!'),
      Notification.createError('ERROR!')
    ]).pipe(
      dematerialize()
    )
  }
  let end = Date.now()
  print("rxjs_test_from(dematerialize): " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function timeouts() {
  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = of(4000, 3000, 2000)
      .pipe(
        concatMap(duration =>
          //@ts-ignore
          makeRequest(duration).pipe(
            timeout(2500),
            catchError(error => of(`Request timed out after: ${duration}`)))
        )
      )
      .subscribe(val => Log.showLog('timeout--' + val));
  }
  let end = Date.now()
  print("rxjs_test_Ark_result_timeout: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}


function asyncs() {
  let observable = new Observable((proxyObserver) => {
    proxyObserver.next(1);
    proxyObserver.next(2);
    proxyObserver.next(3);
    proxyObserver.complete();
  }).pipe(
    observeOn(asyncScheduler)
  );
  let finalObserver = {
    next(x) {
      Log.showLog('async--got value ' + x)
    },
    error(err) {
      Log.showError('async--something wrong occurred: ' + err);
    },
    //@ts-ignore
    complete() {
      Log.showLog('async--done');
    }
  };
  Log.showLog('async--just before subscribe');
  observable.subscribe(finalObserver);
  Log.showLog('async--just after subscribe');

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = new Observable((proxyObserver) => {
      proxyObserver.next(1);
      proxyObserver.next(2);
      proxyObserver.next(3);
      proxyObserver.complete();
    }).pipe(
      observeOn(asyncScheduler)
    );
  }
  let end = Date.now()
  print("rxjs_test_asyncScheduler: " + (end - start) + ' us')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function asaps() {

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = from([1, 2], asapScheduler);
  }
  let end = Date.now()
  print("rxjs_test_asapScheduler: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function queues() {

  let arr = new Array(10)
  let s = 0
  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = queueScheduler.schedule(() => {
      queueScheduler.schedule(() => { s = 1 });
      s = 1;
    });
  }
  let end = Date.now()
  print("rxjs_test_queueScheduler: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function shares() {
  const source = timer(2000);
  const example = source.pipe(
    tap(() => Log.showLog('***SIDE EFFECT***')),
    mapTo('***RESULT***')
  );
  const subscribe = example.subscribe(val => Log.showLog('share--' + val));
  const subscribeTwo = example.subscribe(val => Log.showLog('share--' + val));
  const sharedExample = example.pipe(share());
  const subscribeThree = sharedExample.subscribe(val => Log.showLog('share--' + val));
  const subscribeFour = sharedExample.subscribe(val => Log.showLog('share--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = example.pipe(share());
  }
  let end = Date.now()
  print("rxjs_test_share: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function shareReplays() {
  const routeEnd = new Subject();
  const lastUrl = routeEnd.pipe(
    tap(_ => Log.showLog('shareReplay--executed')),
    pluck('url'),
    shareReplay(1)
  );
  const initialSubscriber = lastUrl.subscribe(Log.showLog);
  routeEnd.next({ data: {}, url: 'my-path' });
  const lateSubscriber = lastUrl.subscribe(Log.showLog);

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = routeEnd.pipe(
      tap(_ => Log.showLog('shareReplay--executed')),
      pluck('url'),
      shareReplay(1)
    );
  }
  let end = Date.now()
  print("rxjs_test_shareReplay: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function publishs() {
  const source = zip(interval(2000), of(1, 2, 3, 4, 5, 6, 7, 8, 9)).pipe(
    map(values => values[1]));
  source.pipe(
    publish(multicasted =>
      merge(
        multicasted.pipe(tap(val => Log.showLog('publish--Stream 1:' + val))),
        multicasted.pipe(tap(val => Log.showLog('publish--Stream 2:' + val))),
        multicasted.pipe(tap(val => Log.showLog('publish--Stream 3:' + val))),
      )
    )
  ).subscribe();

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      publish(multicasted =>
        merge(
          multicasted.pipe(tap(val => Log.showLog('publish--Stream 1:' + val))),
          multicasted.pipe(tap(val => Log.showLog('publish--Stream 2:' + val))),
          multicasted.pipe(tap(val => Log.showLog('publish--Stream 3:' + val))),
        )
      )
    ).subscribe()
  }
  let end = Date.now()
  print("rxjs_test_publish: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function multicasts() {
  // multicast操作�?多播的实现�?需要开�?multicasted.connect();
  const source = from([1, 2, 3]);
  const subject1 = new Subject();
  const multicasted = source.pipe(multicast(subject1))
  multicasted.subscribe({
    next: (v) => Log.showLog(`multicast--A:${v}`)
  })
  multicasted.subscribe({
    next: (v) => Log.showLog(`multicast--B:${v}`)
  })
  multicasted.connect();

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(multicast(subject1))
  }
  let end = Date.now()
  print("rxjs_test_pipe(multicast): " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function debounces() {
  const example = of('WAIT', 'ONE', 'SECOND', 'Last will display');
  const debouncedExample = example.pipe(debounce(() => timer(2000)));
  const subscribe = debouncedExample.subscribe(val => Log.showLog('debounce--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = example.pipe(debounce(() => timer(2000)));
  }
  let end = Date.now()
  print("rxjs_test_debounce: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function debounceTimes() {
  const example = interval(500).pipe(take(7));
  const debouncedInput = example.pipe(debounceTime(2000));
  const subscribe = debouncedInput.subscribe(val => {
    Log.showLog(`debounceTime--${val}`);
  });

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = example.pipe(debounceTime(2000));
  }
  let end = Date.now()
  print("rxjs_test_debounceTime: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function distinctUntilChangeds() {
  const myArrayWithDuplicatesInARow = from([1, 1, 2, 2, 3, 1, 2, 3]);

  const distinctSub = myArrayWithDuplicatesInARow
    .pipe(distinctUntilChanged())
    .subscribe(val => Log.showLog('distinctUntilChanged--' + val));

  const nonDistinctSub = myArrayWithDuplicatesInARow
    .subscribe(val => Log.showLog('distinctUntilChanged--' + val));

  let arr = new Array(10)
  let s = 0
  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = myArrayWithDuplicatesInARow
      .pipe(distinctUntilChanged())
      .subscribe(val => s = 0);
  }
  let end = Date.now()
  print("rxjs_test_distinctUntilChanged(subscribe): " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function filters() {
  const source = from([1, 2, 3, 4, 5]);
  const example = source.pipe(filter(num => num % 2 === 0));
  const subscribe = example.subscribe(val => Log.showLog(`filter--${val}`));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(filter(num => num % 2 === 0));
  }
  let end = Date.now()
  print("rxjs_test_filter: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function firsts() {
  const source = from([1, 2, 3, 4, 5]);
  const example = source.pipe(first());
  const subscribe = example.subscribe(val => Log.showLog(`first--${val}`));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(first());
  }
  let end = Date.now()
  print("rxjs_test_first: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function ignoreElementss() {
  const source = interval(100);
  const example = source.pipe(
    take(5),
    ignoreElements()
  );
  const subscribe = example.subscribe(
    val => Log.showLog(`ignoreElements--NEXT: ${val}`),
    val => Log.showLog(`ignoreElements--ERROR: ${val}`),
    () => Log.showLog('ignoreElements--COMPletE!')
  );

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      take(5),
      ignoreElements()
    );
  }
  let end = Date.now()
  print("rxjs_test_ignoreElements: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function lasts() {
  const source = from([1, 2, 3, 4, 5]);
  const example = source.pipe(last());
  const subscribe = example.subscribe(val => Log.showLog(`last--${val}`));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(last());
  }
  let end = Date.now()
  print("rxjs_test_last: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }


}

function samples() {
  const source = interval(2000);
  const example = source.pipe(sample(interval(2000)), take(5));
  const subscribe = example.subscribe(val => Log.showLog('sample--' + val))

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(sample(interval(2000)), take(5));
  }
  let end = Date.now()
  print("rxjs_test_sample: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function singles() {
  const source = from([1, 2, 3, 4, 5]);
  const example = source.pipe(single(val => val === 4));
  const subscribe = example.subscribe(val => Log.showLog('single--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(single(val => val === 4));
  }
  let end = Date.now()
  print("rxjs_test_single: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function skips() {
  const source = interval(2000);
  const example = source.pipe(skip(5), take(4));
  const subscribe = example.subscribe(val => Log.showLog('skip--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(skip(5), take(4));
  }
  let end = Date.now()
  print("rxjs_test_skip: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function skipUntils() {
  const source = interval(2000);
  const example = source.pipe(skipUntil(timer(6000)), take(4));
  const subscribe = example.subscribe(val => Log.showLog('skipUntil--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(skipUntil(timer(6000)), take(4))
  }
  let end = Date.now()
  print("rxjs_test_skipUntil: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function skipWhiles() {
  const source = interval(2000);
  const example = source.pipe(skipWhile(val => val < 5), take(4));
  const subscribe = example.subscribe(val => Log.showLog('skipWhile--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(skipWhile(val => val < 5), take(4));
  }
  let end = Date.now()
  print("rxjs_test_skipWhile: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function takes() {
  const source = of(1, 2, 3, 4, 5);
  const example = source.pipe(take(1));
  const subscribe = example.subscribe(val => Log.showLog('take--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(take(1));
  }
  let end = Date.now()
  print("rxjs_test_take: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function takeUntils() {
  const source = interval(2000);
  const timer$ = timer(5000);
  const example = source.pipe(takeUntil(timer$));
  const subscribe = example.subscribe(val => Log.showLog('takeUntil--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(takeUntil(timer$))
  }
  let end = Date.now()
  print("rxjs_test_takeUntil: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function takeWhiles() {
  const source = of(1, 2, 3, 4, 5);
  const example = source.pipe(takeWhile(val => val <= 4));
  const subscribe = example.subscribe(val => Log.showLog('takeWhile--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(takeWhile(val => val <= 4))
  }
  let end = Date.now()
  print("rxjs_test_takeWhile: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function throttles() {
  const source = interval(2000);
  const example = source.pipe(throttle(val => interval(2000)), take(4));
  const subscribe = example.subscribe(val => Log.showLog('throttle--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(throttle(val => interval(2000)), take(4));
  }
  let end = Date.now()
  print("rxjs_test_throttle: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function catchErrors() {
  const source = throwError('This is an error!');
  const example = source.pipe(catchError(val => of(`I caught: ${val}`)));
  const subscribe = example.subscribe(val => Log.showLog('catchError--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(catchError(val => of(`I caught: ${val}`)));
  }
  let end = Date.now()
  print("rxjs_test_catchError: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function retrys() {
  const source = interval(2000);
  const example = source.pipe(
    mergeMap(val => {
      return of(val);
    }),
    retry(2)
  );
  const subscribe = example.subscribe({
    next: val => Log.showLog('retry--' + val),
    error: val => Log.showLog(`retry--${val}: Retried 2 times then quit!`)
  });

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      retry(2)
    );
  }
  let end = Date.now()
  print("rxjs_test_retry: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function retryWhens() {
  const source = interval(2000).pipe(take(10));
  const example = source.pipe(
    map(val => {
      if (val > 5) {
        throw val;
      }
      return val;
    }),
    retryWhen(errors =>
      errors.pipe(
        tap(val => Log.showLog(`retryWhen--Value ${val} was too high!`)),
        delayWhen(val => timer(val * 2000))
      )
    )
  );
  let count = 0;
  const that = this;
  const subscribe = example.subscribe({
    next: (val) => {
      Log.showLog(val + '')
      // @ts-ignore
      count += val
      if (count >= 30) {
        // that.close(subscribe);
      }
    }
  });

  let arr = new Array(10)

  let s = 0
  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      map(val => {
        if (val > 5) {
          throw val;
        }
        return val;
      }),
      retryWhen(errors =>
        errors.pipe(
          tap(val => s = 1),
          delayWhen(val => timer(val * 2000))
        )
      )
    );
  }
  let end = Date.now()
  print("rxjs_test_retryWhen: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}


function creates() {
  const observable = Observable.create((observer) => {
    observer.next('Hello');
    observer.next('World');
    // setTimeout(() => {
    //@ts-ignore
    observer.complete();
    //}, 2000);
  });
  const observer = {
    next: x => Log.showLog('create--' + x),
    error: err => Log.showError('create--Observer got an error: ' + err),
    //@ts-ignore
    complete: () => Log.showLog('create--complete'),
  };
  const subscription = observable.subscribe(observer);

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = Observable.create((observer) => {
      observer.next('Hello');
      observer.next('World');
      //setTimeout(() => {
      //@ts-ignore
      observer.complete();
      //}, 2000);
    })
  }
  let end = Date.now()
  print("rxjs_test_create(observer): " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function emptys() {
  let s = 0
  const subscribe = empty().subscribe({
    next: () => s = 1,
    //@ts-ignore
    complete: () => s = 2
  });

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = empty().subscribe({
      next: () => s = 1,
      //@ts-ignore
      complete: () => s = 2
    })
  }
  let end = Date.now()
  print("rxjs_test_empty: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function fromArrays() {

  const arraySource = from([1, 2, 3, 4, 5]);
  const subscribe = arraySource.subscribe(val => {
    Log.showLog('from--' + val)
  });

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = from([1, 2, 3, 4, 5])
  }
  let end = Date.now()
  print("rxjs_test_from: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

//  function intervalNums() {
//
//    const source = interval(2000);
//    const subscribe = source.subscribe(val => {
//      Log.showLog('interval--' + val)
//      if (val > 4) {
//        subscribe.unsubscribe();
//      }
//    });

//   let arr = new Array(10)

//    let len = arr.length
//    let start = Date.now()
//    for (let i = 0; i < 20000; i++) {
//     arr[i % len] = interval(2000);
// }
//    let end = Date.now()
//    result +=("interval: " + ((end - start)/2) + ' ms'+"\n")
//    for (let i = 0; i < 10; i++) {
//      if (arr[i] == null) {
//        print("test fail")
//      }
//    }
//  }

function ofNums() {

  const source = of(1, 2, 3, 4, 5);
  const subscribe = source.subscribe(val => Log.showLog('of--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = of(1, 2, 3, 4, 5);
  }
  let end = Date.now()
  print("rxjs_test_of: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function rangs() {
  const source = range(1, 10);
  const example = source.subscribe(val => Log.showLog('rang--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = range(1, 10);
  }
  let end = Date.now()
  print("rxjs_test_range(subscribe): " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function bufferCounts() {
  const source = interval(2000);
  const bufferThree = source.pipe(bufferCount(3), take(4));
  const subscribe = bufferThree.subscribe(val => {
    Log.showLog('bufferCount--' + val);
  });

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(bufferCount(3), take(4));
  }
  let end = Date.now()
  print("rxjs_test_bufferCount: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function bufferTimes() {
  const source = interval(500);
  const example = source.pipe(bufferTime(2000), take(4));
  const subscribe = example.subscribe(val => Log.showLog('bufferTime--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(bufferTime(2000), take(4));
  }
  let end = Date.now()
  print("rxjs_test_bufferTime: " + (end - start) + ' ms' )
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function bufferToggles() {

  const sourceInterval = interval(2000);
  const startInterval = interval(5000);
  const closingInterval = val => {
    Log.showLog(`Value ${val} emitted, starting buffer! Closing in 3s!`);
    return interval(3000);
  };
  const bufferToggleInterval = sourceInterval.pipe(
    bufferToggle(startInterval, closingInterval),
    take(4)
  );
  const subscribe = bufferToggleInterval.subscribe(val =>
    Log.showLog('bufferToggle--' + val)
  );

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = sourceInterval.pipe(
      bufferToggle(startInterval, closingInterval),
      take(4)
    );
  }
  let end = Date.now()
  print("rxjs_test_bufferToggle: " + (end - start) + ' ms' )
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function bufferWhens() {

  const oneSecondInterval = interval(2000);
  const fiveSecondInterval = () => interval(5000);
  const bufferWhenExample = oneSecondInterval.pipe(bufferWhen(fiveSecondInterval), take(4));
  const subscribe = bufferWhenExample.subscribe(val => {
    Log.showLog('bufferWhen--' + val)
  });


  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = oneSecondInterval.pipe(bufferWhen(fiveSecondInterval), take(4));
  }
  let end = Date.now()
  print("rxjs_test_bufferWhen: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function concatMaps() {
  const source = of(2000, 2000);
  const example = source.pipe(
    concatMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
  );
  const subscribe = example.subscribe(val => {
    Log.showLog(`concatMap--${val}`);
  });
  const mergeMapExample = source
    .pipe(
      delay(5000),
      mergeMap(val => of(`Delayed by: ${val}ms`)
        .pipe(delay(val)))
    )
    .subscribe(val => Log.showLog(`concatMap--${val}`));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      concatMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
    );
  }
  let end = Date.now()
  print("rxjs_test_concatMap: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function concatMapTos() {
  const sampleInterval = interval(500).pipe(take(5));
  let fakeRequest = of('Network request complete').pipe(delay(3000));
  const example = sampleInterval.pipe(concatMapTo(fakeRequest));
  const subscribe = example.subscribe(val => Log.showLog('concatMapTo--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = sampleInterval.pipe(concatMapTo(fakeRequest));
  }
  let end = Date.now()
  print("rxjs_test_concatMapTo: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function exhaustMaps() {
  const sourceInterval = interval(2000);
  const delayedInterval = sourceInterval.pipe(delay(2000), take(4));

  const exhaustSub = merge(
    delayedInterval,
    of(true)
  )
    .pipe(exhaustMap(_ => sourceInterval.pipe(take(5))))
    .subscribe(val => Log.showLog('exhaustMap--' + val));


  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = merge(
      delayedInterval,
      of(true)
    )
      .pipe(exhaustMap(_ => sourceInterval.pipe(take(5))))
      .subscribe(val => Log.showLog('exhaustMap--' + val));
  }
  let end = Date.now()
  print("rxjs_test_exhaustMap: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function expands() {
  const source = of(2);
  const example = source.pipe(
    expand(val => {
      Log.showLog(`expand--${val}`);
      return of(1 + val);
    }),
    take(5)
  );
  const subscribe = example.subscribe(val => Log.showLog(`expand--${val}`));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      expand(val => {
        Log.showLog(`expand--${val}`);
        return of(1 + val);
      }),
      take(5)
    );
  }
  let end = Date.now()
  print("rxjs_test_expand: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function groupBys() {

  const people = [
    {
      name: 'Sue', age: 25
    },
    {
      name: 'Joe', age: 30
    },
    {
      name: 'Frank', age: 25
    },
    {
      name: 'Sarah', age: 35
    }
  ];
  const source = from(people);
  const example = source.pipe(
    groupBy(person => person.age),
  );
  const subscribe = example.subscribe(val => Log.showLog('groupBy--' + JSON.stringify(val)));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      groupBy(person => person.age),
    );
  }
  let end = Date.now()
  print("rxjs_test_groupBy: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function maps() {
  const source = from([1, 2, 3, 4, 5]);
  const example = source.pipe(map(val => val + 10));
  const subscribe = example.subscribe(val => Log.showLog('map--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(map(val => val + 10));
  }
  let end = Date.now()
  print("rxjs_test_map: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function mapTos() {
  const source = interval(2000);
  const example = source.pipe(mapTo('HELLO WORLD!'));
  let count = 0;
  const subscribe = example.subscribe(val => {
    Log.showLog('mapTo--' + val);
    count++;
    if (count > 2) {
      subscribe.unsubscribe();
    }
  });

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(mapTo('HELLO WORLD!'));
  }
  let end = Date.now()
  print("rxjs_test_mapTo: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function mergeMaps() {
  const source = of('Hello');
  const example = source.pipe(mergeMap(val => of(`${val} World!`)));
  const subscribe = example.subscribe(val => Log.showLog('mergeMap--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(mergeMap(val => of(`${val} World!`)));
  }
  let end = Date.now()
  print("rxjs_test_mergeMap: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function plucks() {
  const source = from([{ name: 'Joe', age: 30 },
  { name: 'Sarah', age: 35 }
  ]);
  const example = source.pipe(pluck('name'));
  const subscribe = example.subscribe(val => Log.showLog('pluck--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(pluck('name'));
  }
  let end = Date.now()
  print("rxjs_test_pluck: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function reduces() {

  const source = of(1, 2, 3, 4);
  const example = source.pipe(reduce((acc, val) => acc + val));
  const subscribe = example.subscribe(val => Log.showLog('reduce--Sum:' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(reduce((acc, val) => acc + val));
  }
  let end = Date.now()
  print("rxjs_test_reduce: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function scans() {

  const source = of(1, 2, 3);
  const example = source.pipe(scan((acc, curr) => acc + curr, 0));
  const subscribe = example.subscribe(val => Log.showLog('scan--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(scan((acc, curr) => acc + curr, 0));
  }
  let end = Date.now()
  print("rxjs_test_scan: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function switchMaps() {
  const source = timer(0, 5000);
  const example = source.pipe(switchMap(() => interval(500)));
  const subscribe = example.pipe(take(18)).subscribe(val => Log.showLog('switchMap--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(switchMap(() => interval(500)));
  }
  let end = Date.now()
  print("rxjs_test_switchMap: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function windows() {

  const source = timer(0, 2000);
  const example = source.pipe(window(interval(3000)));
  const count = example.pipe(scan((acc, curr) => acc + 1, 0), take(2));
  const subscribe = count.subscribe(val => Log.showLog(`Window ${val}:`));
  const subscribeTwo = example.pipe(mergeAll(), take(6)).subscribe(val => Log.showLog('window--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(window(interval(3000)));
  }
  let end = Date.now()
  print("rxjs_test_window: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function windowCounts() {
  const source = interval(2000);
  const example = source.pipe(
    windowCount(4),
    //@ts-ignore
    tap(_ => Log.showLog('NEW WINDOW!')));

  let arr = new Array(10)
  for (let i = 0; i < 10; i++) {
    arr.push(new Observable())
  }
  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      windowCount(4),
      tap(_ => Log.showLog('NEW WINDOW!')));
  }
  let end = Date.now()
  print("rxjs_test_windowCount: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function windowTimes() {
  let startTime = new Date().valueOf()
  const source = timer(0, 2000);
  const example = source.pipe(
    windowTime(3000),
    tap(_ => Log.showLog('NEW WINDOW!'))
  );
  const subscribeTwo = example
    .pipe(mergeAll(), take(6)).subscribe(val => Log.showLog('windowTime--' + val));

  let arr = new Array(10)
  for (let i = 0; i < 10; i++) {
    arr.push(new Observable())
  }
  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      windowTime(3000),
      tap(_ => Log.showLog('NEW WINDOW!'))
    );
  }
  let end = Date.now()
  print("rxjs_test_windowTimes: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function windowToggles() {

  const source = timer(0, 2000);
  const toggle = interval(5000);
  const example = source.pipe(
    windowToggle(toggle, val => interval(val * 2000)),
    tap(_ => Log.showLog('NEW WINDOW!'))
  );
  const subscribeTwo = example
    .pipe(mergeAll(), take(6)).subscribe(val => Log.showLog('windowToggle--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      windowToggle(toggle, val => interval(val * 2000)),
      tap(_ => Log.showLog('NEW WINDOW!'))
    );
  }
  let end = Date.now()
  print("rxjs_test_windowToggle: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function windowWhens() {
  const source = timer(0, 2000);
  const example = source.pipe(
    windowWhen(() => interval(5000)),
    tap(_ => Log.showLog('NEW WINDOW!'))
  );
  const subscribeTwo = example
    .pipe(mergeAll(), take(10)).subscribe(val => Log.showLog('windowWhen--' + val));


  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      windowWhen(() => interval(5000)),
      tap(_ => Log.showLog('NEW WINDOW!'))
    );
  }
  let end = Date.now()
  print("rxjs_test_windowWhen: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function partitions() {
  const observableValues = from([1, 2, 3, 4, 5, 6]);
  const [evens, odds] = partition(observableValues, (value, index) => value % 2 === 0);
  const subscribe = merge(
    evens.pipe(map(val => `Even: ${val}`)),
    odds.pipe(map(val => `Odd: ${val}`))
  ).subscribe(val => Log.showLog('partition--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = partition(observableValues, (value, index) => value % 2 === 0);
  }
  let end = Date.now()
  print("rxjs_test_partition: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function everys() {
  const source = of(1, 2, 3, 4, 5);
  const example = source.pipe(
    every(val => val % 2 === 0)
  );
  const subscribe = example.subscribe(val => Log.showLog('every--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      every(val => val % 2 === 0)
    );
  }
  let end = Date.now()
  print("rxjs_test_every: " + (end - start) + ' ms' )
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function combineAlls() {

  const source = interval(2000).pipe(take(2)); //0,1
  const example = source.pipe(
    map(val => interval(2000)
      .pipe(map(i => `Result (${val}): ${i}`), take(5)))
  );
  //print("ex:" + Object.keys(example))
  const combined = example.pipe(combineAll());

  const subscribe = combined.subscribe(val => Log.showLog('combineAll--' + val));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = example.pipe(combineAll())
  }
  let end = Date.now()
  print("rxjs_test_combineAll: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function combineLatests() {
  const timerOne = timer(2000, 4000).pipe(take(3));
  const timerTwo = timer(2000, 4000).pipe(take(3));
  const timerThree = timer(3000, 4000).pipe(take(3));

  const combinedProject = combineLatest(
    timerOne,
    timerTwo,
    timerThree,
    (one, two, three) => {
      return `Timer One (Proj) Latest: ${one},
              Timer Two (Proj) Latest: ${two},
              Timer Three (Proj) Latest: ${three}`;
    });
  const subscribe = combinedProject.subscribe(latestValuesProject => {
    Log.showLog('combineLatest--' + latestValuesProject);
  });
  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = combineLatest(
      timerOne,
      timerTwo,
      timerThree,
      (one, two, three) => {
        return `Timer One (Proj) Latest: ${one},
              Timer Two (Proj) Latest: ${two},
              Timer Three (Proj) Latest: ${three}`;
      });
  }
  let end = Date.now()
  print("rxjs_test_combineLatest: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function concatObservables() {
  const sourceOne = of(1, 2, 3);
  const sourceTwo = of(4, 5, 6);
  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    //@ts-ignore
    arr[i % len] = sourceOne.pipe(concat(sourceTwo));
  }
  let end = Date.now()
  print("rxjs_test_concatObservable: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}



function concatAlls() {
  const obs1 = interval(2000).pipe(take(5));
  const obs2 = interval(500).pipe(take(2));
  const obs3 = interval(2000).pipe(take(1));
  const source = of(obs1, obs2, obs3);

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(concatAll());
  }
  let end = Date.now()
  print("rxjs_test_concatAll: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function forkJoins() {
  const myPromise = val =>
    new Promise(resolve =>
      setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000));

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = forkJoin(
      of('Hello'),
      of('World')
        .pipe(delay(2000)),
      interval(2000)
        .pipe(take(1)),
      interval(2000)
        .pipe(take(2)),
      myPromise('RESULT')
    );
  }
  let end = Date.now()
  print("rxjs_test_forkJoin: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function merges() {
  const first = interval(2500);
  const second = interval(2000);

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    //@ts-ignore
    arr[i % len] = first.pipe(merge(second), take(6));
  }
  let end = Date.now()
  print("rxjs_test_merge: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function mergeAlls() {
  const myPromise = val =>
    new Promise(resolve => setTimeout(() => resolve(`Result: ${val}`), 2000));
  const source = of(1, 2, 3);

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(
      map(val => myPromise(val)),
      mergeAll());
  }
  let end = Date.now()
  print("rxjs_test_mergeAll: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function pairwises() {
  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = interval(2000).pipe(
      pairwise(),
      take(5)
    );
  }
  let end = Date.now()
  print("rxjs_test_pairwise: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function races() {

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = race(
      interval(1500),
      interval(2000)
        .pipe(mapTo('1s won!')),
      interval(2000),
      interval(2500)
    ).pipe(take(2));
  }
  let end = Date.now()
  print("rxjs_test_race: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }

}

function startWiths() {
  const source = of(1, 2, 3);

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(startWith(0));
  }
  let end = Date.now()
  print("rxjs_test_startWith: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function withLatestFroms() {
  const source = interval(5000);
  const secondSource = interval(2000);

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = source.pipe(// @ts-ignore
      withLatestFrom(secondSource),
      map(([first, second]) => {
        return `First Source (5s): ${first} Second Source (1s): ${second}`;
      }),
      take(5)
    );
  }
  let end = Date.now()
  print("rxjs_test_withLatestFrom: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function zips() {
  const sourceOne = of('Hello');
  const sourceTwo = of('World!');
  const sourceThree = of('Goodbye');
  const sourceFour = of('World!');

  let arr = new Array(10)

  let len = arr.length
  let start = Date.now()
  for (let i = 0; i < 20000; i++) {
    arr[i % len] = zip(
      sourceOne,
      sourceTwo.pipe(delay(2000)),
      sourceThree.pipe(delay(2000)),
      sourceFour.pipe(delay(3000))
    )
  }
  let end = Date.now()
  print("rxjs_test_zip: " + (end - start) + ' ms')
  for (let i = 0; i < 10; i++) {
    if (arr[i] == null) {
      print("test fail")
    }
  }
}

function main() {

  create_Test()
  range_Test();
  distinctUntilChanged_Test();
  multicast_Test();
  concat_Test();
  throwError_Test();
  defaultIfEmpty_Test();
  dematerialize_Test();
  observeOn_Test();

  retryWhens()
  skipWhiles()
  timeouts()
  exhaustMaps()
  combineAlls();
  combineLatests();
  //concatObservables();
  concatAlls();
  forkJoins();
  mergeAlls();
  pairwises();
  races();
  startWiths();
  withLatestFroms();
  zips();
  everys()
  bufferCounts()
  bufferTimes()
  bufferToggles()
  bufferWhens()
  concatMaps()
  concatMapTos()
  expands()
  groupBys()
  maps()
  mapTos()
  mergeMaps()
  plucks()
  reduces()
  scans()
  switchMaps()
  windows()
  windowCounts()
  windowTimes()
  windowToggles()
  windowWhens()
  partitions()
  taps()
  delays()
  delayWhens()
  dematerializes()
  asyncs()
  asaps()
  queues()
  shares()
  shareReplays()
  publishs()
  multicasts()
  debounces()
  debounceTimes()
  distinctUntilChangeds()
  filters()
  firsts()
  ignoreElementss()
  lasts()
  samples()
  singles()
  skips()
  skipUntils()
  takes()
  takeUntils()
  takeWhiles()
  throttles()
  catchErrors()
  retrys()
  // retryWhen()
  creates()
  emptys()
  fromArrays()
  // intervalNums()
  ofNums()
  rangs()
}

let loopCountForPreheat = 1;
for (let i = 0; i < loopCountForPreheat; i++) {
    main();
}

ArkTools.waitAllJitCompileFinish();

main();
